package com.foreveross.chameleon.socket;

import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import com.foreveross.chameleon.utils.AppLog;
import com.foreveross.chameleon.utils.GeneralUtils;
import com.foreveross.chameleon.utils.Preferences;

/**
 * project:
 * author: wzq
 * date: 2014/7/21
 * description: 建立socket = 获取token 验证token 建立socket连接
 */
public class PushSetup {
    private SocketConnect currPushSocket = null;
    private static int setupFailTime = 0; // setup失败次数,成功后 此值清零
    private static int RECONNECT_INTERVAL = 10 * 1000; //失败重连间隔 ms
    private boolean isServiceStart = false;
    private String currUserName = null;

    private static PushSetup instance;
    private PushSetup() {
    }
    public static PushSetup getInstance() {
        if(instance == null) {
            instance = new PushSetup();
        }
        return instance;
    }

    /**
     * 注册推送的消息拦截器
     */
    public void registerMsgInterceptor(PushRTx.MsgInterceptor msgInterceptor) {
        PushRTx.registerMsgInterceptor(msgInterceptor);
    }

    public String getUserName() {
        return currUserName;
    }

    /**
     * 所有变量初始化，然后进行连接，会断开当前连接，重新开始
     *
     * @param description 描述，仅作为log打印
     * @param fromService 是否从Service启动
     * @param switchUser 是否从切换用户启动
     */
    public void startSetup(String description, boolean fromService, boolean switchUser) {
        if(isServiceStart && fromService) {
            // 避免service重复启动push socket连接
            //AppLog.e("service 启动push,但是已经启动");
            return;
        }

        if(switchUser) {
            SystemClock.sleep((int) (Math.random() * 100));
            String toUser = Preferences.getCurrentUserName();
            if(toUser != null && toUser.equals(currUserName)) {
                // 编码重复切换
                //AppLog.e("切换用户,但切换到当前用户 " + toUser);
                return;
            } else {
                currUserName = toUser;
            }
        }

        //AppLog.i("-------开始建立socket连接-----");
        //AppLog.i(description);
        stopSetup(false);

        // 检测网络
        if(!GeneralUtils.isNetworkConnected()) {
            //AppLog.e("无网络连接 push流程结束");
            return;
        }

        if(setupFailTime > 0) { // 表示上一次未成功
            // waiting for a while
            //AppLog.i("setup 已连续失败 " + setupFailTime + " 次");
            SystemClock.sleep(RECONNECT_INTERVAL);
        }

        // 检测token -> 获取token
        new TokenGetter().getToken(new TokenGetter.OnTokenGetted() {
            @Override
            public void tokenGetted(String token, String userName) {
                currUserName = userName;
                if(null == token || "".equals(token)) {
                    //AppLog.e("push 获取token失败");
                    setupFinish(false);
                    stopSetup(false);
                } else {
                    onRegisterSucc(token, "succ");
                    //onTokenGetSucc(token);
                }
            }
        });

        //
        if(fromService) {
            isServiceStart = fromService;
        }
    }

//    // 获取有效【非空，非过期】token后的流程
//    private void onTokenGetSucc(final String token) {
//        //AppLog.i("获取token成功 - > 验证token");
//        new TokenValidator().register(token, new TokenValidator.OnRegResult() {
//            @Override
//            public void handleRegResult(boolean isSucc, final String value) {
//                if(isSucc) {
//                    onRegisterSucc(token, value);
//                } else {
//                    AppLog.e("PushSetup", "push 注册Token失败");
//                    setupFinish(false);
//                    stopSetup(false);
//                }
//            }
//        });
//    }

    // token 注册 socket 成功后,连接socket服务器
    private void onRegisterSucc(final String token, String value) {
        //AppLog.i("验证token 成功 -> socket连接");
        //AppLog.i("value = " + value);
        // 清除当前的socket对象
        stopSetup(false);

        // 连接
        new Thread() {
            public void run() {
                final SocketConnect s = new SocketConnect();
                s.connect();

                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        if(s.isAvailiable()) {
                            AppLog.d("PushSetup","socket连接 成功 -> PushRTx 启动");
                            setupFinish(true);
                            currPushSocket = s;
                            PushRTx.startRTx(currPushSocket, token);
                        } else {
                            AppLog.e("PushSetup","socket 连接失败");
                            setupFinish(false);
                            stopSetup(false);
                        }
                    }
                });
            }
        }.start();
    }

    /**
     * 结束当前的Push流程,如果socket 已经建立 并在使用中，则终止该socket连接
     */
    public void stopSetup(boolean fromService) {
        // TODO:
        if(fromService) {
            isServiceStart = false;
            instance = null;
        }
        PushRTx.stopRTx();
        if(currPushSocket != null) {
            currPushSocket.disConnect();
            currPushSocket = null;
        }
    }

    // socket 收发发生异常时调用
    public void socketRTxErr() {
        // TODO:
        setupFinish(false);
        startSetup("PushRTx 错误，要求重连", false, false); // 重连
    }

    public void setupFinish(boolean isSucc) {
        if(isSucc) {
            setupFailTime = 0;
        } else {
            setupFailTime++;
        }
    }
}
